﻿/***************************************************************************
 * 工    具：  HKMonoUtility
 * 
 * 描    述：  Mono单例工具类
 * 
 * 版    本：  V1.1
 * 作    者：  京产肠饭、谭潇杰
 * 
 * 创    建：  2024/05/01  V1.0
 * 
 * 更    新：  2024/10/21  V1.1
 *            1.功能新增：新增通过 HTTP Post ，获取Json的泛型方法
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
****************************************************************************/

using HKTools;
using QFramework;
using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class HKMonoUtility : MonoSingleton<HKMonoUtility>
{
    /// <summary>
    /// 从 StreamingAssets 中获取Json文件并解析，通过callback返回
    /// </summary>
    public void GetJsonFromStreamingAssets<T>(string filePath, Action<T> callback) where T : class
    {
        StartCoroutine(IE_GetJson(filePath, callback, false));
    }

    /// <summary>
    /// 通过 HTTP Get 获取Json数据并解析，通过callback返回
    /// </summary>
    public void GetJsonFromURL<T>(string url, Action<T> callback, string header = "", string end = "") where T : class
    {
        StartCoroutine(IE_GetJson(url, callback, true, header, end));
    }

    IEnumerator IE_GetJson<T>(string url, Action<T> callback, bool isURL, string header = "", string end = "") where T : class
    {
        UnityWebRequest request;

        // 是否为完整路径
        bool isFullPath = true;

        if (isURL) // 如果是从 URL 中拉取
        {
            request = UnityWebRequest.Get(url);
        }
        else // 如果是从 StreamingAssets中 拉取
        {
            url = Application.streamingAssetsPath + "/" + url;

            if (!url.EndsWith(".json", StringComparison.OrdinalIgnoreCase) && !url.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
            {
                url += ".json";
                isFullPath = false;
            }

            request = UnityWebRequest.Get(url);
        }

        yield return request.SendWebRequest();

        // 如果通过拼 .json 路径尝试失败后，再次尝试 .txt
        if (request.error != null && !isFullPath && !isURL)
        {
            url = url.Replace(".json", ".txt");
            request = UnityWebRequest.Get(url);
            yield return request.SendWebRequest();
        }

        if (request.error != null)
        {
            HKDebug.LogError("请求 " + url + " 文件错误！");
        }
        else
        {
            string dataStr = request.downloadHandler.text;

            if (isURL && header != "")
            {
                dataStr = header + dataStr + end;
            }

            HKDebug.Log("获取的json数据为：" + dataStr);
            T t = JsonUtility.FromJson<T>(dataStr);
            callback?.Invoke(t);
        }
    }

    /// <summary>
    /// 通过 HTTP Post 获取Json数据并解析，通过callback返回
    /// </summary>
    public void POSTJsonFromURL<T, U>(string url, U postData, Action<T> callback, Action errorCallback = null) where T : class where U : class
    {
        StartCoroutine(IE_POSTJson(url, postData, callback));
    }

    IEnumerator IE_POSTJson<T, U>(string url, U postData, Action<T> callback, Action errorCallback = null) where T : class where U : class
    {
        string json = JsonUtility.ToJson(postData);

        UnityWebRequest request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
        DownloadHandler downloadHandler = new DownloadHandlerBuffer();
        request.downloadHandler = downloadHandler;
        request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
        byte[] bodyRaw = Encoding.UTF8.GetBytes(json);
        request.uploadHandler = new UploadHandlerRaw(bodyRaw);
        yield return request.SendWebRequest();

        if (request.error != null)
        {
            HKDebug.LogError("POST请求 " + url + " 文件错误！" + request.error);
            errorCallback?.Invoke();
        }
        else
        {
            HKDebug.Log(request.downloadHandler.text, LogColor.Green);
            T jsonClass = JsonUtility.FromJson<T>(request.downloadHandler.text);
            callback(jsonClass);
        }
    }

    /// <summary>
    /// 从 StreamingAssets 中加载Sprite，通过callback返回
    /// </summary>
    public void GetSpriteFromStreamingAssets(string texturePath, Action<Sprite> callback)
    {
        StartCoroutine(IE_GetSpriteFromStreamingAssets(texturePath, callback));
    }

    IEnumerator IE_GetSpriteFromStreamingAssets(string texturePath, Action<Sprite> callback)
    {
        if (!texturePath.StartsWith("/"))
        {
            texturePath = "/" + texturePath;
        }

        string path = Application.streamingAssetsPath + texturePath;

        UnityWebRequest request = UnityWebRequestTexture.GetTexture(path);

        yield return request.SendWebRequest();

        if (request.result != UnityWebRequest.Result.Success)
        {
            HKDebug.LogError("请求 " + texturePath + " 文件错误！");
        }
        else
        {
            Texture2D texture = DownloadHandlerTexture.GetContent(request);
            Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
            callback?.Invoke(sprite);
        }
    }
}
